#ifndef __LOCALMAP_H__
#define __LOCALMAP_H__
#include "../include/Typedef.hpp"
#include "../include/Frame.hpp"
#include "../include/MapPoint.hpp"
#include "../include/Matcher.hpp"
#include "../include/Param.hpp"
#include "../include/Optimizer.hpp"
#include "../include/Debuger.hpp"
#include "../include/KeyFrameDatabase.hpp"
#include "../include/LoopClosing.hpp"
#include <mutex>
namespace ORBSLAM{
    class LoopClosing;
    class LocalMap
    {
    private:
        /* data */
        LoopClosing* mp_loopclosing;
    public:
        LocalMap(KeyFrameDatabase* p_keyframe_database);
        ~LocalMap();

        void Set_param(Param * p_param);

        void Set_map(Map * p_map);

        void Set_loopclosing(LoopClosing* p_loopclosing);

        void Insert_keyframe(KeyFrame * p_keyframe);

        list<KeyFrame*> mlp_new_keyframe;
        bool mb_abort_ba;

        void Update_local_keyframe(Frame &cur_frame);
        void Update_local_mappoint(Frame &cur_frame);

        bool Check_if_new_keyframe_exist();

        void Process_new_keyframe();

        void Mappoint_culling();

        void Create_new_mappoint();

        void Keyframe_culling();

        Matx33f ComputeF12(KeyFrame* &p_keyframe1,KeyFrame* &p_keyframe2);

        Matx33f Skew_symmetric_matrix(const Matx31f &v);

        void Search_in_neighbors();

        void Run();

        bool Stop();
        bool Is_stoped();
        bool Check_finish();
        void Reset_if_requested();

        void Set_accept_keyframe(bool flag);

        void Set_finish();

        bool Accept_keyframes();

        bool Set_not_stop(bool flag);

        void Interrupt_ba();

        int Keyframe_in_queue();

        void Request_stop();
        void Empty_queue();

        void Release();

        vector<KeyFrame*> mvp_local_keyframe;
        vector<MapPoint*> mvp_local_mappoint;


        bool mb_stop_request;
        bool mb_not_stop;
        bool mb_stoped;
        bool mb_finished;
        bool mb_finish_requested;
        bool mb_reset_requested;
        bool mb_accept_keyframe;

        mutex mmutex_accept;
        mutex mmutex_new_keyframe;
        mutex mmutex_stop;
        mutex mmutex_finish;
        mutex mmutex_reset;
        

        KeyFrame* mp_current_keyframe;

        KeyFrameDatabase* mp_keyframe_database;

        Matcher * mp_matcher;

        list<MapPoint*> mlp_recently_added_mappoints;

        Param *mp_param;

        Map* mp_cur_map;
        
    };

    
}
#endif // __LOCALMAP_H__